<?php

declare(strict_types=1);

namespace app\posapi\controller;

use think\facade\Db; //门面模式
use app\posapi\model\SellPos as mysql; //导入模型
// POS销售单据

class SellPos
{
    public function index($rrs)
    {
        return 'SellPos/index.POS销售单据' . $rrs;
    }
    // HTTP请求
    function curl_HTTP($url, $header, $pos_db)
    {
        return false;
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);  // 从证书中检查SSL加密算法是否存在
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, 0); //如果想把一个头包含在输出中，设置这个选项为一个非零值。
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //如果成功只将结果返回，不自动输出任何内容。
        curl_setopt($ch, CURLOPT_POST, 1); //设置为POST方式
        curl_setopt($ch, CURLOPT_POSTFIELDS, $pos_db); //POST数据
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
        curl_setopt($ch, CURLINFO_HEADER_OUT, 1); //启用时追踪句柄的请求字符串。
        $response = curl_exec($ch);
        //dump(curl_error($ch));  //查看报错信息
        // 写文件
        // file_put_contents('ajs/web_api_' . date('Y-m-d_H-i-s', time()) . '.json', $response . "\n", FILE_APPEND);
        curl_close($ch);
        return $response;
    }

    // POS销售-预下单
    public function NewDbid()
    {
        $query = request()->param(); //请求参数
        //验证规则
        $vali_db = [
            'operator' => $query["operator"], //门店操作员
        ];
        $validate = new \app\posapi\validate\SellPos_NewDbid; //验证规则
        if (!$validate->check($vali_db)) {
            // 验证不过关提示
            $apidb = [
                'code' => 201, //状态码
                'msg' => "请求参数有误-" . $validate->getError(),
                'requestdb' => $query,
                'validate' => $validate->getError(),
            ];
            return json($apidb);
        }
        $dbid = "91" . date('ymdHis', time()) . rand(1000, 9999); //订单：前缀+2位年月日时分秒+四位随机数。例： "dbid": "9231114190243"
        // 订单表头写入
        $sqldb = mysql::create(
            [
                'dbid' => $dbid, //数据编号.唯一(系统单号)
                'state' => 'C', //单据状态_A挂单B结算C空单
                'operator' => $query["operator"] ? $query["operator"] : '门店操作员', //门店操作员
                'sign' => base64_encode(md5('sign' . $dbid)), //改单签名串
            ]
        );
        if ($sqldb) {
            $code = 200;
            $msg = "生成下一笔销售单号-成功";
            $data_now = $sqldb->toArray();
        }


        // API信息
        $help = [
            "code" => "错误代码",
            "time" => "接口运行时间",
            "msg" => "状态信息",
            "query=接口请求参数包" => [
                "operator" => "门店操作员"
            ],
            "db=接口回调核心数据包" => [
                "state" => "单据状态_A挂单B已结算(锁定)C预下单号D草稿单E支付中(锁定)E已整单退货",
                "dbid" => "单号",
                "sign" => "改单签名串",
                "operator" => "门店操作员"

            ]
        ];


        $apidb = [
            'code' => $code, //状态码
            'time' => time(), //
            'msg' => $msg, //状态信息
            'query' => request()->param(), //请求参数
            'db' => $data_now,
            "接口信息" => ["name" => "预下单", "notice" => "部分字段可能不返回，没用到的字段不要预设，部分描述文字可能有错误。", "help" => $help], //API信息
        ];
        return (json($apidb));
    }
    // POS销售-保存销售单
    public function PosOrderSave()
    {
        $query = request()->param(); //请求参数

        // 调用控制器模块
        $PosOrder = new \app\posapi\controller\classPosOrder;
        $db = $PosOrder->posorder($query);
        return (json($db));
    }
    // POS销售-获取销售单
    public function PosOrderId()
    {
        $query = request()->param(); //请求参数
        // 查单头
        $sqldb = mysql::where(['dbid' => $query["dbid"]])->findOrEmpty();
        // 查询返回空
        if ($sqldb->isEmpty()) {
            $apidb = [
                'code' => 201, //状态码
                'time' => time(), //运行时间

                'msg' => "订单不存在", //状态信息
            ];
            return $apidb;
        }
        ;
        //设置需要输出的属性
        $data = $sqldb->visible([
            'id', //主键
            "dbid",
            // "sign",
            "type",
            "state",
            "time_new",
            "time_up",
            "detail_length_query",
            "detail_length_insert",
            "remark",
            "operator",
            "total_price",
            "total_discount",

        ]);
        // 设置需要隐藏的输出属性
        $data = $data->hidden([
            //     'id', //主键
        ]);
        // 设置需要附加的输出属性
        $data = $data->append([
            'goods_db', //附加字段-单据明细
        ]);

        // POS销售单据关联商品
        $order_detail = Db::table('ai_sell_pos_order_detail')->where(['order_dbid' => $sqldb["dbid"]])->select();
        $data["goods_db"] = $order_detail->toArray();


        // API信息
        $help = [
            "code" => "错误代码",
            "time" => "接口运行时间",
            "msg" => "状态信息",
            "query=接口请求参数包" => [
                "dbid" => "要获取销售单单号"
            ],
            "db=接口回调核心数据包" => [
                "state" => "单据状态_A挂单B已结算(锁定)C预下单号D草稿单E支付中(锁定)E已整单退货",
                "dbid" => "数据编号.唯一(系统单号)",
                "sign" => "改单签名串",
                "type" => "单据类型_A1销售B1退货",
                "detail_length_query" => "明细请求长度",
                "detail_length_insert" => "明细写入长度",
                "operator" => "门店操作员",
                "total_price" => "整单总价",
                "total_discount" => "整单折扣",
                "tm_code" => "终端机器码",
                "tm_id" => "机器号",
                "time_new" => "计算属性-创建时间",
                "time_up" => "计算属性-修改时间",
                "remark" => "单据备注",
                "goods_db=商品数据数组包" =>
                    [
                        "barcode" => "条码",
                        "goods_dbid" => "商品数据编号",
                        "goods_name" => "商品名称",
                        "in_code" => "录入码",
                        "number" => "数量",
                        "order_dbid" => "对应订单数据编号",
                        "prc_sale_actual_sum" => "实际-零售价-小计",
                        "prc_sale_actual" => "实际-零售价",
                        "prc_sale" => "档案-零售价（原零售价）",
                        "remark" => "单行备注",
                        "unit_pack" => "是否大单位_A是B否",
                        "unit" => "单位",
                    ]
            ]
        ];
        $apidb = [
            "code" => 200, //状态码
            "time" => time(), //运行时间
            "msg" => "获取销售单-成功", //状态信息
            "query" => $query,
            "db" => $data,
            "接口信息" => ["name" => "获取销售单", "notice" => "部分字段可能不返回，没用到的字段不要预设，部分描述文字可能有错误。", "help" => $help], //API信息


        ];
        return (json($apidb));
    }





    //修改
    public function up()
    {
        $query = request()->param(); //请求参数
        $time_int = time();
        $time = date('Y-m-d H:i:s', $time_int);

        // 查单头
        $sqldb = mysql::where('dbid', '=', $query["table_header"]["dbid"])->findOrEmpty();

        // 查询返回空
        if ($sqldb->isEmpty()) {
            $apidb = [
                'code' => 201, //状态码
                'msg' => "查询不到相关单据", //状态信息
                'query' => $query, //请求参数
                'data' => [],
            ];
            return (json($apidb));
        }

        // 单据状态_A草稿B审核C作废
        if ($sqldb['state'] != 'A') {
            $apidb = [
                'code' => 205, //状态码
                'msg' => "此单据不能修改", //状态信息
                'query' => $query, //请求参数
                'data' => $sqldb,
            ];
            return (json($apidb));
        }


        $sqldb->time_up = $time_int; //修改时间
        $sqldb->save();


        // 修改单头-成功
        if ($sqldb) {
            $code = 200;
            $msg = "查单头-成功";
            $sqldb = $sqldb->toArray();


            // <删除数据库的>
            // 再增加新商品
            // 查询单据明细数据
            $detail_db = Db::table('ai_sell_pos_order_detail')->where('order_dbid', $sqldb["dbid"])->select();


            // 删除数据库的
            if ($detail_db) {
                for ($i = 0; $i < count($detail_db); $i++) {
                    $deleteok = Db::table('ai_sell_pos_order_detail')->where('order_dbid', '=', $sqldb["dbid"])->delete();
                }
            }



            $cr = $query["table_detail"]; //订单明细数据
            for ($i = 0; $i < count($cr); $i++) {
                $insert_data[$i]["order_dbid"] = $sqldb["dbid"]; //对应订单数据编号
                $insert_data[$i]["goods_dbid"] = $cr[$i]["goods_dbid"]; //商品数据编号
                $insert_data[$i]["number"] = $cr[$i]["number"]; //数量
                $insert_data[$i]["prc_in"] = $cr[$i]["prc_in"]; //档案进价
                $insert_data[$i]["prc_in_actual"] = $cr[$i]["prc_in_actual"]; //实际进价
                $insert_data[$i]["unit"] = $cr[$i]["unit"]; //单位
                $insert_data[$i]["in_code"] = $cr[$i]["in_code"]; //录入码
                $insert_data[$i]["barcode"] = $cr[$i]["barcode"]; //条码
                $insert_data[$i]["remark"] = $cr[$i]["remark"]; //单行备注
            }
            // 写入订单头成功-得到订单号后-写入订单明细
            //分批写入每次最多100条数据
            $sql_insert_table_detail = Db::name('ai_sell_pos_order_detail')
                ->strict(false)
                ->limit(100)
                ->insertAll($insert_data);

            if ($sql_insert_table_detail) {
                $code = 200;
                $msg = "单据保存-成功";
                // 更新订单头字段-明细写入长度
                $mysql_data_now = mysql::where('dbid', '=', $sqldb["dbid"])->find();
                $mysql_data_now->detail_length_insert = $sql_insert_table_detail; //明细写入长度
                $mysql_data_now->time_up = $time_int; //修改时间

                $mysql_data_now->save();
                if ($sql_insert_table_detail != count($query["table_detail"])) {
                    $code = 203;
                    $msg = "订单明细写入-成功-但条目不相等";
                }
                $data_now = $sqldb;
            } else {
                $code = 202;
                $msg = "订单明细写入-失败";
            }
        } else {
            $code = 201;
            $msg = "订单表头修改-失败";
            $data_now = [];
        }



        $apidb = [
            'code' => $code, //状态码
            'msg' => $msg, //状态信息
            'query' => $query, //请求参数
            'data' => $data_now,
        ];
        return (json($apidb));
    }
    // 查询一条单据
    public function id()
    {
        $query = request()->param(); //请求参数
        // 查单头
        if (isset($query["dbid"]) && $query["dbid"] != "") {
            $sqldb = mysql::where('dbid', '=', $query["dbid"])->find(); //精准查询
        } else {
            $sqldb = mysql::order("id", "desc")->find(); //空查返回最新一条数据
        }
        ;




        // 单据头部-成功-查明细
        if ($sqldb) {
            //设置需要输出的属性
            $sqldb = $sqldb->visible([
                //     'id', //主键
            ]);
            // 设置需要隐藏的输出属性
            $sqldb = $sqldb->hidden([
                //     'id', //主键
            ]);
            // 设置需要附加的输出属性
            $sqldb = $sqldb->append([
                'table_detail', //附加字段-单据明细
            ]);
            // 设置数据字段获取器
            $sqldb = $sqldb->withAttr('db_state', function ($value, $data) {
                $res = ["A" => '删除', "B" => '停用', "C" => '只销'];
                return ["val" => $value, "mp" => $res[$value], "txt" => "商品状态"];
            });
            $sqldb = $sqldb->withAttr('unit_pack', function ($value, $data) {
                $res = ["A" => '是', "B" => '否'];
                return ["val" => $value, "mp" => $res[$value], "txt" => "是否大单位"];
            });
            $sqldb = $sqldb->withAttr('time_new', function ($value, $data) {
                return ["val" => $value, "mp" => date('Y-m-d H:i:s', $value), "txt" => "创建时间"];
            });
            $sqldb = $sqldb->withAttr('time_up', function ($value, $data) {
                return ["val" => $value, "mp" => date('Y-m-d H:i:s', $value), "txt" => "修改时间"];
            });

            // 查单头成功查单据明细

            $sql_table_detail = Db::table('ai_sell_pos_order_detail')
                ->where('order_dbid', '=', $sqldb['dbid'])
                ->order("id", "desc")
                ->withAttr('unit_pack', function ($value, $data) {
                    // 设置数据字段获取器
                    $res = ["A" => '是', "B" => '否'];
                    return ["val" => $value, "mp" => $res[$value], "txt" => "是否大单位"];
                })
                ->select()
                ->toArray();
            if ($sql_table_detail) {
                $code = 200;
                $msg = "查询明细-成功";
                $sqldb["table_detail"] = $sql_table_detail;
            } else {
                $code = 200;
                $msg = "查询明细-成功-0条";
                $sqldb["table_detail"] = [];
            }

            $sqldb->detail_length_insert = count($sql_table_detail); //明细写入长度
            $sqldb->save();
        } else {
            $code = 201;
            $msg = "单据不存在";
            $sqldb["table_detail"] = [];
        }

        $apidb = [
            'code' => $code, //状态码
            'msg' => $msg, //状态信息
            'query' => $query, //请求参数
            'data' => $sqldb,
        ];
        return (json($apidb));
    }
    // 列表
    public function List()
    {
        $query = request()->param(); //请求参数
        $limit = request()->param('limit', 10, 'trim'); //每页行数
        $current = request()->param('current', 1, 'trim'); //页码

        if ($query["additional"]["use"] == 1) {
            // additional.use启用额外查询方法-0否-1是。
            $SearchField = $query["additional"]["SearchField"]; //搜索字段
            $SearchOperator = $query["additional"]["SearchOperator"]; //搜索查询表达式
            $SearchaAtistop = $query["additional"]["SearchaAtistop"]; //搜索关键词SearchaAtistop:"[4,28,29,30,31,32,33,34]"

        } else {
            $SearchField = request()->param('SearchField', 'id', 'trim'); //搜索字段
            $SearchOperator = request()->param('SearchOperator', 'LIKE', 'trim'); //搜索查询表达式
            $SearchaAtistop = strval(request()->param('SearchaAtistop', "", 'trim')); //搜索关键词

        }
        $SearchaSort = request()->param('SearchaSort', 'DESC', 'trim'); //搜索排序方式ASE,DESC升降序
        $SearchaSortField = request()->param('SearchaSortField', 'id', 'trim'); //排序字段

        // 查询表达式
        if ($SearchOperator == 'LIKE') {
            $SearchaAtistop = '%' . $SearchaAtistop . '%';
        }
        ;
        if ($SearchField == 'time_new' || $SearchField == 'time_up') {
            if ($SearchOperator == '>' || $SearchOperator == '<') {
                $SearchaAtistop = strtotime(strval($SearchaAtistop));
                if ($SearchField == 'time_new') {
                    $SearchField = 'time_new';
                } else if ($SearchField == 'time_up') {
                    $SearchField = 'time_up';
                }
            }
        }
        $help = [
            "db" => [
                "total" => "数据总行数",
                "per_page" => "每页数量",
                "current_page" => "当前页码",
                "last_page" => "最后一页/总页数",
                "data" => "数据集",
                "SearchaAtistop" => $SearchaAtistop
            ]
        ];
        $sqldb = mysql::where([
            [$SearchField, $SearchOperator, $SearchaAtistop],
            // ["cls_id", "IN", [1, 150, 129, 128, 123, 124, 154, 120, 121, 122]],
            // ["state", "=", "B"], //单据状态_A草稿B审核C作废

        ])
            ->order($SearchaSortField, $SearchaSort)
            ->paginate([ //[文档]https://www.kancloud.cn/manual/thinkphp6_0/1037638
                'list_rows' => $limit, // 每页数量
                'page' => $current, // 当前页
                // 'query' => $query,//url额外参数
            ]);



        // 设置数据字段获取器
        //   单据类型_A1采购入库B1采购退货C1赠品入库D1报损出库
        $sqldb = $sqldb->withAttr('type', function ($value, $data) {
            $res = ["A1" => '采购入库', "B1" => '采购退货', "C1" => '赠品入库', "D1" => '报损出库'];
            return ["val" => $value, "mp" => $res[$value], "txt" => "单据类型"];
        });
        // 单据状态_A草稿B审核C作废
        $sqldb = $sqldb->withAttr('state', function ($value, $data) {
            $res = ["A" => '草稿', "B" => '审核', "C" => '作废'];
            return ["val" => $value, "mp" => $res[$value], "txt" => "单据状态"];
        });
        $sqldb = $sqldb->withAttr('time_new', function ($value, $data) {
            return ["val" => $value, "mp" => date('Y-m-d H:i:s', $value), "txt" => "创建时间"];
        });
        $sqldb = $sqldb->withAttr('time_up', function ($value, $data) {
            return ["val" => $value, "mp" => date('Y-m-d H:i:s', $value), "txt" => "修改时间"];
        });


        $sqldb2 = $sqldb->toArray();


        //  当前页起始行
        if ($current > 1) {
            $index2 = $limit * $current - $limit + 1;
        } else {
            $index2 = 1;
        }
        // echo "当前总下标：" . $index2;
        for ($x = 0; $x < count($sqldb); $x++) {
            $sqldb2["data"][$x]['index1'] = $x + 1;
            $sqldb2["data"][$x]['index2'] = $index2;
            $index2++;

            $reset = null;
            // $reset = Db::table('ai_t_goods_cls')->where('id', $sqldb2["data"][$x]['cls_id'])->find();

            // $sqldb2["data"][$x]['cls_name'] = !empty($reset["name"]) ? $reset["name"] : "!断链分类" . $sqldb2["data"][$x]['cls_id'];



        }
        $apidb = [
            'api' => ["name" => "采购单据列表", "help" => $help], //API信息
            'code' => 200, //状态码
            'msg' => "查询成功！", //状态信息
            'query' => $query, //请求参数
            'data' => $sqldb2,

        ];
        return (json($apidb));
    }
    // 审核-写库存
    public function Finish()
    {
        $query = request()->param(); //请求参数
        $time_int = time();
        $time = date('Y-m-d H:i:s', $time_int);

        // 查单头
        $sqldb = mysql::where([
            ['dbid', '=', $query["table_header"]["dbid"]],
            // ['state', '=', 'A'], //单据状态_A草稿B审核C作废
        ])->findOrEmpty();

        // 查询返回空
        if ($sqldb->isEmpty()) {
            $apidb = [
                'code' => 201, //状态码
                'msg' => "查询不到相关单据", //状态信息
                'query' => $query, //请求参数
                'data' => [],
            ];
            return (json($apidb));
        } else {
            // 单据状态_A草稿B审核C作废
            if ($sqldb['state'] != 'A') {
                $apidb = [
                    'code' => 205, //状态码
                    'msg' => "此单据不能审核", //状态信息
                    'query' => $query, //请求参数
                    'data' => $sqldb,
                ];
                return (json($apidb));
            }
            ;

            // 获取-单据明细
            $sql_detail = Db::table('ai_sell_pos_order_detail')->where('order_dbid', '=', $sqldb['dbid'])->select();
            if ($sql_detail) {
                // 遍历-单据明细
                foreach ($sql_detail as $item) {
                    // dump($item['goods_dbid']); //商品数据编号
                    // dump($item['number']); //数量
                    $detail_id = Db::table('ai_t_goods_stock')->where('goods_dbid', '=', $item['goods_dbid'])->find(); //查-库存信息
                    if ($detail_id) {
                        // 库存信息-存在-累加
                        $number = $detail_id["number"] + $item['number'];
                        //更新库存
                        $update = Db::name('ai_t_goods_stock')->where('goods_dbid', '=', $item['goods_dbid'])->update(['number' => $number]);
                        if ($update) {
                            // 更新库存-成功
                            $code = 200; //状态码
                            $msg = "审核成功"; //状态信息
                            $sqldb->time_up = $time_int; //修改时间
                            $sqldb->state = "B"; //单据状态_A草稿B审核C作废
                            $sqldb->save();
                        } else {
                            $code = 201; //状态码
                            $msg = "审核-失败"; //状态信息
                        }
                    } else {
                        // 库存信息-不存在-新增
                        $data = ['goods_dbid' => $item['goods_dbid'], 'number' => $item['number']];
                        $insert_id = Db::name('ai_t_goods_stock')->insert($data);
                        if ($insert_id) {
                            // 写入库存信息-成功
                            // dump($insert_id);
                            $code = 200; //状态码
                            $msg = "审核成功"; //状态信息
                            $sqldb->time_up = $time_int; //修改时间
                            $sqldb->state = "B"; //单据状态_A草稿B审核C作废
                            $sqldb->save();
                        } else {
                            $code = 202; //状态码
                            $msg = "审核-失败"; //状态信息
                        }
                    }
                }
            } else {
                $code = 203; //状态码
                $msg = "审核失败-单据明细没数据"; //状态信息
            }
        }



        $apidb = [
            'code' => $code, //状态码
            'msg' => $msg, //状态信息
            'query' => $query, //请求参数
            'data' => $sqldb,
        ];
        return (json($apidb));
    }
}
